﻿using Abp.Domain.Repositories;
using System.Threading.Tasks;
using Utils;
using Abp.Domain.Services;
using Microsoft.AspNetCore.Identity;
using shenghua.Authorization.Users;
using System;
using Abp.UI;
using System.Linq;
using System.Collections.Generic;
using Abp.Domain.Entities;
using shenghua.Authorization;
using shenghua.Basics.MemberLevels;
using shenghua.Basics;

namespace shenghua.Member.Members
{
    public class MemberManager : DomainService
    {
        private readonly IRepository<Member, long> _memberRepository;
        private readonly IRepository<Commodity.Commodities.Commodity> _commodityRepository;
        private readonly UserManager _userManager;
        private readonly MemberLevelManager _memberLevelManager;
        private readonly SettingManager _settingManager;

        public MemberManager(
            IRepository<Member, long> memberRepository,
            IRepository<Commodity.Commodities.Commodity> commodityRepository,
            UserManager userManager,
            MemberLevelManager memberLevelManager,
            SettingManager settingManager
            )
        {
            _memberRepository = memberRepository;
            _commodityRepository = commodityRepository;
            _userManager = userManager;
            _memberLevelManager = memberLevelManager;
            _settingManager = settingManager;
        }

        public async Task<Member> Create(string userName, string password, string name, string phone, string email)
        {
            var query = _memberRepository.GetAll();
            if (query.Where(r => r.UserName == userName).Count() > 0)
            {
                throw new ApplicationException("用户名已存在");
            }
            if (query.Where(r => r.PhoneNumber == phone).Count() > 0)
            {
                throw new ApplicationException("手机号已被使用");
            }
            if (query.Where(r => r.EmailAddress == email).Count() > 0)
            {
                throw new ApplicationException("邮箱已被使用");
            }
            Member member = Member.CreateMember(userName, name, phone, email);
            var result = await this._userManager.CreateAsync(member, password);
            if(!result.Succeeded)
            {
                throw new UserFriendlyException(result.Errors.First().Description);
            }
            // 设置等级
            await SetLevel(member, 1);
            return member;
        }

        public async Task<Member> Create(Member member, string password)
        {
            await this._userManager.CreateAsync(member, password);
            return member;
        }

        public async Task<Member> Update(Member member, string password = null)
        {
            if(password != null)
            {
                await _userManager.ChangePasswordAsync(member, password);
            }
            return member;
        }

        public async Task Delete(long id)
        {
            await _memberRepository.DeleteAsync(id);
        }

        public async Task<int> CalculateLevelWithTotalXPValue(int totalXPValue)
        {
            var items = await _memberLevelManager.GetAll();
            foreach(var item in items)
            {
                if(item.NeededXPValue >= totalXPValue)
                {
                    return item.Level;
                }
            }
            return 1;
        }

        public async Task SetLevel(Member member, int level, string description = null)
        {
            MemberLevel memberLevel = await _memberLevelManager.GetByLevel(level);
            member.Level = level;
            // 设置等级对应的角色
            await SetRoles(member, memberLevel.Roles.Items);
        }

        public async Task SetLevel(long memberId, int level, string description = null)
        {
            Member member = await Get(memberId);
            await SetLevel(member, level, description);
        }

        public async Task SetRoles(Member member, List<string> roleNames)
        {
            await _userManager.SetRoles(member, roleNames.ToArray());
        }

        public async Task<Member> Get(long memberId)
        {
            Member member = await _memberRepository.GetAsync(memberId);
            if(member == null)
            {
                throw new UserFriendlyException("会员不存在");
            }
            return member;
        }

        public async Task ChangePassword(Member member, string currentPassword, string newPassword)
        {
            await _userManager.ChangePasswordAsync(member, currentPassword, newPassword);
        }
    }
}
